﻿using System;
using System.Collections.Generic;
using System.Linq;
using yiCommerce.Core;
using yiCommerce.Core.Data;
using yiCommerce.Core.Domain.Orders;
using yiCommerce.Core.Domain.Payments;
using yiCommerce.Core.Domain.Shippings;

namespace yiCommerce.Service.Orders
{
    public class OrderService:IOrderService
    {
        private IRepository<Order> _orderRepository;

        public OrderService(IRepository<Order> orderRepository)
        {
            _orderRepository = orderRepository;
        }

        public Order GetOrderById(int orderId)
        {
            return _orderRepository.GetById(orderId);
        }

        public void DeleteOrder(Order order)
        {
            throw new NotImplementedException();
        }

        public IList<OrderSearchResult> SearchOrders(int customerId, int shopId, DateTime? startTime, DateTime? endTime, OrderStatus? os, PaymentStatus? ps,
                                       ShippingStatus? ss, int pageIndex, int pageSize)
        {
            int? orderStatusId = null;
            if (os.HasValue)
                orderStatusId = (int)os.Value;

            int? paymentStatusId = null;
            if (ps.HasValue)
                paymentStatusId = (int)ps.Value;

            int? shippingStatusId = null;
            if (ss.HasValue)
                shippingStatusId = (int)ss.Value;

            var query = _orderRepository.Table;
            if (startTime.HasValue)
                query = query.Where(o => startTime.Value <= o.CreatedOnUtc);
            if (endTime.HasValue)
                query = query.Where(o => endTime.Value >= o.CreatedOnUtc);
            if (orderStatusId.HasValue)
                query = query.Where(o => orderStatusId.Value == o.OrderStatusId);
            if (paymentStatusId.HasValue)
                query = query.Where(o => paymentStatusId.Value == o.PaymentStatusId);
            if (shippingStatusId.HasValue)
                query = query.Where(o => shippingStatusId.Value == o.ShippingStatusId);

            if (customerId != 0)
            {
                query = from o in query
                        where o.CustomerId == customerId
                        select o;
            }

            if (shopId != 0)
            {
                query = from o in query
                        where o.ShopId == shopId
                        select o;

            }

            query = query.Where(o => !o.Deleted);
            query = query.OrderByDescending(o => o.CreatedOnUtc);

            var tempResult = new PagedList<Order>(query, pageIndex, pageSize);
            var result = tempResult.ToList().Select(c => new OrderSearchResult()
                {
                    Id = c.Id,
                    OrderTotal =  c.OrderTotal.ToString(),
                    OrderStatusStr = ((OrderStatus)c.OrderStatusId).ToDesc(),
                    PaymentStatusStr = ((PaymentStatus)c.PaymentStatus).ToDesc(),
                    ShippingStatusStr = ((ShippingStatus)c.ShippingStatus).ToDesc(),
                    CustomerEmail = c.Customer.Email,
                    CreatedOn = c.CreatedOnUtc.ToString("yyyy-MM-dd HH:mm:ss"),
                    OrderStatus = c.OrderStatus,
                    PaymentStatus = c.PaymentStatus,
                    ShippingStatus = c.ShippingStatus,
                }).ToList();
            return result;
        }

        public IList<Order> GetOrdersByCustomerId(int customerId)
        {
            throw new NotImplementedException();
        }

        public void InsertOrder(Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            _orderRepository.Insert(order);
        }

        public void UpdateOrder(Order order)
        {
            if (order == null)
                throw new ArgumentNullException("order");

            _orderRepository.Update(order);
        }

        public OrderProductVariant GetOrderProductVariantById(int orderProductVariantId)
        {
            throw new NotImplementedException();
        }

        public void DeleteOrderProductVariant(OrderProductVariant orderProductVariant)
        {
            throw new NotImplementedException();
        }

        public IList<Order> GetOrdersByTradeId(int tradeId)
        {
            var query = from o in _orderRepository.Table
                        from t in o.Tradings
                        where t.TradingId == tradeId
                        select o;
            return query.ToList();
        }

        public Order GetOrderByIdAndCustomerId(int orderId, int customerId)
        {
            return _orderRepository.Table.Where(c => c.Id == orderId && c.CustomerId == customerId).FirstOrDefault();
        }
    }
}